﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MIMSDomain.Entities;
using MIMSDomain.Abstract;
using MIMSDomain.Concrete;
using Moq;

namespace MIMSUnitTests.Domain
{
    [TestClass]
    public class EFAllergyRepositoryTests
    {


        public readonly IRepository<Allergy> MockAllergyRepository;

        public EFAllergyRepositoryTests()
        {
            //Arrange
            var _Allegies = new List<Allergy>{
                new Allergy{Id=1, Name="ABC", AllergyType = AllergyType.Drug},
                new Allergy{Id=2, Name="CDE",AllergyType = AllergyType.Drug},
                new Allergy{Id=3, Name="EDF",AllergyType = AllergyType.Drug},
                new Allergy{Id=4, Name="GHI",AllergyType = AllergyType.Drug}
            };

            //Mock the  Repository
            var target = new Mock<IRepository<Allergy>>();
            target.Setup(p => p.All).Returns(_Allegies.AsQueryable());
            target.Setup(p => p.GetById(It.IsAny<int>())).Returns((int i) =>
                _Allegies.Where(p => p.Id == i).Single());
            target.Setup(p => p.Save(It.IsAny<Allergy>())).Returns((Allergy objAllergy) =>
                {
                    if (objAllergy.Id.Equals(default(int)))
                    {
                        objAllergy.Id = _Allegies.Count() + 1;
                        _Allegies.Add(objAllergy);
                    }
                    else
                    {
                        var original = _Allegies.Where(p => p.Id == objAllergy.Id).Single();
                        if (original == null)
                        {
                            return false;
                        }
                        original.Name = objAllergy.Name;
                    }
                    return true;
                });
            target.Setup(p => p.Delete(It.IsAny<Allergy>())).Returns((Allergy objAllergy) =>
                {

                    if (_Allegies.Contains(objAllergy))
                    {
                        _Allegies.Remove(objAllergy);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            
            MockAllergyRepository = target.Object;
        }
        
        [TestMethod]
        public void CanSave()
        {
            //Arrange
            var count = MockAllergyRepository.All.Count();
            //Assert
            Assert.AreEqual(4, count); //Confirm Allergy count
            //Act
            var expected = MockAllergyRepository.Save(new Allergy{ Name= "ROC",AllergyType=AllergyType.Drug });

            //Assert
            count = MockAllergyRepository.All.Count();
            Assert.AreEqual(5, count); //Confirm allergy count after saving

        }

        [TestMethod]
        public void CannotAddDuplicate()
        {
            //Arrange
            var count = MockAllergyRepository.All.Count();
            //Assert
            Assert.AreEqual(4, count); //Confirm Allergy count
            //Act
            var expected = MockAllergyRepository.Save(new Allergy { Name = "ROC", AllergyType = AllergyType.Drug });

            //Assert
            count = MockAllergyRepository.All.Count();
            Assert.AreEqual(5, count); //Confirm allergy count after saving
        }

        [TestMethod]
        public void CanGetById()
        {
            //Act
            var expected = MockAllergyRepository.GetById(3);
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected,typeof(Allergy));
            Assert.AreEqual(expected.Name, "EDF");
        }

        [TestMethod]
        public void CanGetAll()
        {
            //Act
            var expected = MockAllergyRepository.All;
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected, typeof(IQueryable<Allergy>));
            Assert.AreEqual(expected.Count(), 4);
        }

        [TestMethod]
        public void CanDelete()
        {
            //Arrange
            var count = MockAllergyRepository.All.Count();
            Assert.AreEqual(4, count);
            var objAllergy = MockAllergyRepository.GetById(3);
            Assert.IsInstanceOfType(objAllergy, typeof(Allergy));
            //Act
            MockAllergyRepository.Delete(objAllergy);
            count = MockAllergyRepository.All.Count();
            //Assert
            Assert.AreEqual(3, count);
        }
        
    }
}
